package com.color.admin.common.core.exception;


import com.color.admin.common.core.result.ResultCode;
import com.color.admin.common.core.result.ResultData;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.transaction.TransactionSystemException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.persistence.RollbackException;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author HaiQiu
 * @date 2021/11/19
 * 全局异常处理器
 */
@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(ExceptionHandler.class);

    @ResponseBody
    @ExceptionHandler(Exception.class)
    public ResultData exception(Exception e) {
        e.printStackTrace();
        LOGGER.debug(e.getMessage());
        if (e instanceof BaseException) {
            return ResultData.fail(((BaseException) e).code,e.getMessage());
        }else if (e instanceof TransactionSystemException){
            //处理注解参数校验嵌套异常
            Throwable cause = e.getCause();
            if (cause instanceof RollbackException){
                if (cause.getCause() instanceof ConstraintViolationException){
                    ConstraintViolationException throwable = (ConstraintViolationException)cause.getCause();
                    String messages = throwable.getConstraintViolations().stream()
                            .map(ConstraintViolation::getMessage).collect(Collectors.joining("；"));
                    return ResultData.fail(ResultCode.INVALID.getCode(),messages);
                }
            }
        }else if (e instanceof MethodArgumentNotValidException){
            MethodArgumentNotValidException throwable = (MethodArgumentNotValidException) e;
            String message = Objects.requireNonNull(throwable.getBindingResult().getFieldError()).getDefaultMessage();
            return ResultData.fail(ResultCode.INVALID.getCode(),message);
        }
        return ResultData.fail(e.getMessage());
    }
}
